﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
#if SILVERLIGHT
using System.Windows.Browser;
using System.Text;
using System.IO;
#endif

namespace Sonce.Common
{
    public class Utils
    {
        #region Members
        private Application app = null;
        private UserControl page = null;
        #endregion

        #region Constructor
        public Utils(Application app, UserControl page)
        {
            this.app = app;
            this.page = page;
        }
        #endregion

        #region Bits and bytes
        /// <summary>
        /// Check if the bit in value is set to 1.
        /// </summary>
        /// <param name="mask">Mask containing bits.</param>
        /// <param name="bit">Position of the bit.</param>
        /// <returns>True if bit is set.</returns>
        public static bool IsSet(int mask, int bit)
        {
            return ((mask & (1 << bit)) > 0);
        }
        #endregion

        #region Html and javascript
        #if SILVERLIGHT
        /// <summary>
        /// Execute javascript code immediately.
        /// </summary>
        /// <param name="js">Javascript code</param>
        public void RunJavascript(string js)
        {
            try
            {
                //HtmlPage.IsEnabled
                HtmlPage.Window.Eval(js);
            }
            catch (Exception ex)
            {
                Logger.Log(ex, (int)LogLevels.Detailed);
            }
        }

        /// <summary>
        /// Call javascript code that should change application's container dimensions.
        /// </summary>
        public void ToggleStretch()
        {
            //RunJavascript("toggleStretch();");
            RunJavascript("alert('toggleStretch();');");
        }

        /// <summary>
        /// Toggle fullscreen mode.
        /// </summary>
        public void ToggleFullscreen()
        {
            this.app.Host.Content.IsFullScreen ^= true;
        }
        #endif
        #endregion

        #region Request and response
        #if SILVERLIGHT
        /// <summary>
        /// Offer a file download. This algorithm is temporary and should be replaced with better one.
        /// Currently the content is sent to server and downloaded again. The trick to offer file as download
        /// is in http header, so that's why it has to be re-sent.
        /// </summary>
        /// <param name="content">Content to be downloaded as file.</param>
        /// <param name="filename">Filename that should be dispalyed in Save As dialog.</param>
        /// <param name="mimeType">Mime type (e.g. "text/plain").</param>
        /// <param name="checksum">True to generate MD5 hash from the content.</param>
        public void ForceDownload(string content, string filename, string mimeType, bool checksum)
        {
            try
            {
                HttpHelper helper = new HttpHelper();
                helper.DownloadStringCompleted += delegate(object sender, HttpHelperEventArgs e)
                {
                    try
                    {
                        //Open url - start downloading in browser
                        HtmlPage.Window.Navigate(e.ResponseUri, "_self");
                    }
                    catch
                    {
                        //May throw security exception if e.Result cannot be retrieved
                    }
                };
                helper.DownloadStringAsync(new Uri(AppConfig.ForceDownloadScript), new Dictionary<string,string>()
                {
                    { "content", content },
                    { "mimetype", mimeType },
                    { "filename", filename },
                    { "checksum", (checksum ? MD5Core.GetHashString(content) : null) },
                });
            }
            catch (Exception ex)
            {
                Logger.Log(ex, LogLevels.Detailed);
            }
        }
        #endif
        #endregion

        #region Conversion
        /// <summary>
        /// Reads a stream and converts it to UTF8 string.
        /// </summary>
        /// <param name="stream">Readable stream.</param>
        /// <returns>Returns UTF8 string.</returns>
        public static string ReadStream(Stream stream)
        {
            string result = null;
            if (stream != null && stream.CanRead)
            {
                int size = 1024;
                byte[] buffer = new byte[size];
                StringBuilder builder = new StringBuilder();
                while ((size = stream.Read(buffer, 0, size)) > 0)
                {
                    //Progress can be asynchronously reported here...
                    builder.Append(Encoding.UTF8.GetString(buffer, 0, buffer.Length));
                }
                result = builder.ToString();
            }
            return result;
        }
        #endregion
    }
}
